﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Windows.Forms;
using System.Xml;

namespace Players_info
{
    public partial class Form1 : Form
    {
        private class SteamGameInfo
        {
            public int AppId;
            public string Name;

            public SteamGameInfo(XmlNode gameInfo)
            {
                this.AppId = Convert.ToInt32(gameInfo["appid"].InnerText);
                this.Name = gameInfo["name"].InnerText;
            }
        }

        private class BNetPlayerInfo
        {
            public int Id;
            public string Name;

            public BNetPlayerInfo(XmlNode info)
            {
                this.Id = Convert.ToInt32(info.FirstChild["id"].InnerText);
                this.Name = info.FirstChild["displayName"].InnerText;
            }
        }

        private class LeagueDetails
        {
            public string Server;
            public string Url;
        }

        private Dictionary<int, int> SteamGameList = new Dictionary<int, int>();
        private Dictionary<int, LeagueDetails> BNetSC2LeaguesList = new Dictionary<int, LeagueDetails>();

        public Form1()
        {
            InitializeComponent();
        }        

        private void buttonSteamFilter_Click(object sender, EventArgs e)
        {
            LoadSteamGames(textBoxFilter.Text == "All" ? null : textBoxFilter.Text);
        }

        private void buttonSteamClear_Click(object sender, EventArgs e)
        {
            LoadSteamGames(null);
        }

        private void buttonBNetSelect_Click(object sender, EventArgs e)
        {            
            LoadBNetPlayers();
        }

        private void buttonSteamHelp_Click(object sender, EventArgs e)
        {
            MessageBox.Show("This tab loads Steam games based on specified parameters. Further it is possible to select one game and display number of current players.");
        }

        private void buttonBNetHelp_Click(object sender, EventArgs e)
        {
            MessageBox.Show("This tab loads Blizzard games based on specified parameters (at the moment only GM leagues for SC II are supported). Further it is possible to select one league and display all recently active players (active in last 15 minutes, all time displayed in UTC).");
        }

        private void buttonSteamSelect_Click(object sender, EventArgs e)
        {
            if (listBoxSteamGameList.SelectedIndex < 0)
            {
                return;
            }

            int appId = SteamGameList[listBoxSteamGameList.SelectedIndex];

            using (var client = new HttpClient())
            {
                client.BaseAddress = new Uri("http://api.steampowered.com/");
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                HttpResponseMessage response = client.GetAsync("ISteamUserStats/GetNumberOfCurrentPlayers/v1/?appid=" + appId).Result;
                if (response.IsSuccessStatusCode)
                {
                    var json = response.Content.ReadAsStringAsync().Result;
                    var data = JsonConvert.DeserializeXmlNode(json);
                    listBoxSteamSelected.Items.Add(string.Format("{0} - {1}", listBoxSteamGameList.Text, data.FirstChild.ChildNodes[0].InnerText));
                }
            }
        }

        private void buttonBNetFilter_Click(object sender, EventArgs e)
        {
            string usgm = "sc2/ladder/194757?apikey=zrxxcy3qzp8jcbgrce2es4yq52ew2k7r";
            string eugm = "sc2/ladder/181958?apikey=zrxxcy3qzp8jcbgrce2es4yq52ew2k7r";
            string krgm = "sc2/ladder/61052?apikey=zrxxcy3qzp8jcbgrce2es4yq52ew2k7r";
            string seagm = "sc2/ladder/16120?apikey=zrxxcy3qzp8jcbgrce2es4yq52ew2k7r";

            listBoxBNetList.Items.Clear();
            int index = listBoxBNetList.Items.Add("US GM");
            BNetSC2LeaguesList.Add(index, new LeagueDetails() { Server = "us", Url = usgm });
            index = listBoxBNetList.Items.Add("EU GM");
            BNetSC2LeaguesList.Add(index, new LeagueDetails() { Server = "eu", Url = eugm });
            index = listBoxBNetList.Items.Add("KR GM");
            BNetSC2LeaguesList.Add(index, new LeagueDetails() { Server = "kr", Url = krgm });
            index = listBoxBNetList.Items.Add("SEA GM");
            BNetSC2LeaguesList.Add(index, new LeagueDetails() { Server = "sea", Url = seagm });
        }

        private void LoadSteamGames(string filter)
        {
            
            using (var client = new HttpClient())
            {
                client.BaseAddress = new Uri("http://api.steampowered.com/");
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                HttpResponseMessage response = client.GetAsync("ISteamApps/GetAppList/v2").Result;
                if (response.IsSuccessStatusCode)
                {
                    var json = response.Content.ReadAsStringAsync().Result;
                    var data = JsonConvert.DeserializeXmlNode(json);

                    var steamGames = from d in data.DocumentElement.ChildNodes.Cast<XmlNode>()
                                     select new SteamGameInfo(d);

                    progressBarSteam.Visible = true;
                    progressBarSteam.Value = 0;
                    progressBarSteam.Maximum = steamGames.Count();

                    int index;
                    listBoxSteamGameList.Items.Clear();
                    SteamGameList.Clear();
                    foreach (SteamGameInfo gameInfo in steamGames)
                    {
                        progressBarSteam.Increment(1);
                        if (!string.IsNullOrEmpty(filter) && !gameInfo.Name.ToLower().Contains(filter.ToLower()))
                        {
                            continue;
                        }

                        index = listBoxSteamGameList.Items.Add(string.Format("{0}: {1}", gameInfo.AppId, gameInfo.Name));
                        SteamGameList.Add(index, gameInfo.AppId);
                    }
                }
            }
            progressBarSteam.Visible = false;
        }

        private void LoadBNetPlayers()
        {
            if (listBoxBNetList.SelectedIndex < 0)
            {
                return;
            }

            LeagueDetails league = BNetSC2LeaguesList[listBoxBNetList.SelectedIndex];
            listBoxBNetSelected.Items.Clear();
            progressBarBNet.Visible = true;
            progressBarBNet.Value = 0;
            
            using (var client = new HttpClient())
            {
                client.BaseAddress = new Uri(string.Format("https://{0}.api.battle.net/", league.Server));
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                HttpResponseMessage response = client.GetAsync(league.Url).Result;
                if (response.IsSuccessStatusCode)
                {
                    var json = response.Content.ReadAsStringAsync().Result;
                    var data = JsonConvert.DeserializeXmlNode(json, "ladderMembers");

                    var players = from d in data.DocumentElement.ChildNodes.Cast<XmlNode>()
                                  select new BNetPlayerInfo(d);

                    foreach (BNetPlayerInfo playerInfo in players)
                    {
                        progressBarBNet.Increment(1);
                        using (var clientPlayer = new HttpClient())
                        {
                            clientPlayer.BaseAddress = new Uri(string.Format("https://{0}.api.battle.net/", league.Server));
                            clientPlayer.DefaultRequestHeaders.Accept.Clear();
                            clientPlayer.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                            HttpResponseMessage responsePlayer = client.GetAsync(string.Format("sc2/profile/{0}/1/{1}/matches?apikey=zrxxcy3qzp8jcbgrce2es4yq52ew2k7r", playerInfo.Id, playerInfo.Name)).Result;
                            if (responsePlayer.IsSuccessStatusCode)
                            {
                                var jsonPlayer = responsePlayer.Content.ReadAsStringAsync().Result;
                                var dataPlayer = JsonConvert.DeserializeXmlNode(jsonPlayer, "matches");
                                var latestMatchDate = dataPlayer.DocumentElement.FirstChild["date"].InnerText;
                                DateTime dt = new DateTime(1970, 1, 1);
                                dt = dt.AddSeconds(Convert.ToInt64(latestMatchDate));

                                TimeSpan difference = DateTime.UtcNow - dt;
                                if (difference < new TimeSpan(0, 15, 0))
                                {
                                    listBoxBNetSelected.Items.Add(string.Format("{0}: {1} - {2}", playerInfo.Id, playerInfo.Name, dt.ToString()));                                   
                                }
                            }
                        }
                    }
                }
            }
            progressBarBNet.Visible = false;
        }               
    }
}
